from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
from django.core.validators import validate_ipv4_address
import json


class DockerServer(models.Model):
    """Docker服务器配置"""
    name = models.CharField(max_length=100, unique=True, verbose_name="服务器名称")
    description = models.TextField(blank=True, verbose_name="描述")

    # 连接配置
    host = models.CharField(max_length=255, verbose_name="服务器地址")
    ssh_port = models.IntegerField(default=22, verbose_name="SSH端口")
    ssh_username = models.CharField(max_length=100, verbose_name="SSH用户名")
    ssh_password = models.CharField(max_length=255, verbose_name="SSH密码")  # 需要加密存储
    ssh_key_path = models.CharField(max_length=500, blank=True, verbose_name="SSH密钥路径")

    # Docker配置
    docker_port = models.IntegerField(default=2376, verbose_name="Docker端口",
                                    help_text="虽然不使用2375端口，但保留配置以备将来使用")
    use_ssh_tunnel = models.BooleanField(default=True, verbose_name="使用SSH隧道")

    # 状态信息
    is_active = models.BooleanField(default=True, verbose_name="是否启用")
    is_default = models.BooleanField(default=False, verbose_name="是否为默认服务器")

    CONNECTION_STATUS_CHOICES = [
        ('unknown', '未知'),
        ('connected', '已连接'),
        ('disconnected', '连接失败'),
        ('error', '错误'),
        ('testing', '测试中'),
    ]
    connection_status = models.CharField(
        max_length=20,
        choices=CONNECTION_STATUS_CHOICES,
        default='unknown',
        verbose_name="连接状态"
    )

    # Docker信息
    docker_version = models.CharField(max_length=50, blank=True, verbose_name="Docker版本")
    docker_api_version = models.CharField(max_length=20, blank=True, verbose_name="Docker API版本")
    system_info = models.JSONField(default=dict, blank=True, verbose_name="系统信息")

    # 统计信息
    total_containers = models.IntegerField(default=0, verbose_name="容器总数")
    running_containers = models.IntegerField(default=0, verbose_name="运行中容器")
    total_images = models.IntegerField(default=0, verbose_name="镜像总数")
    total_volumes = models.IntegerField(default=0, verbose_name="数据卷总数")
    total_networks = models.IntegerField(default=0, verbose_name="网络总数")

    # 时间戳
    last_check_time = models.DateTimeField(null=True, blank=True, verbose_name="最后检查时间")
    last_sync_time = models.DateTimeField(null=True, blank=True, verbose_name="最后同步时间")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    # 创建者
    created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="创建者")

    class Meta:
        verbose_name = "Docker服务器"
        verbose_name_plural = "Docker服务器"
        ordering = ['-is_default', '-created_at']

    def __str__(self):
        return f"{self.name} ({self.host})"

    def save(self, *args, **kwargs):
        # 确保只有一个默认服务器
        if self.is_default:
            DockerServer.objects.filter(is_default=True).exclude(pk=self.pk).update(is_default=False)
        super().save(*args, **kwargs)

    def get_ssh_connection_info(self):
        """获取SSH连接信息"""
        return {
            'host': self.host,
            'port': self.ssh_port,
            'username': self.ssh_username,
            'password': self.ssh_password,
            'key_path': self.ssh_key_path if self.ssh_key_path else None
        }


class DockerRegistry(models.Model):
    """Docker镜像仓库配置"""
    name = models.CharField(max_length=100, unique=True, verbose_name="仓库名称")
    url = models.URLField(verbose_name="仓库地址")

    # 仓库类型
    REGISTRY_TYPE_CHOICES = [
        ('dockerhub', 'Docker Hub'),
        ('harbor', 'Harbor'),
        ('private', '私有仓库'),
        ('aliyun', '阿里云'),
        ('tencent', '腾讯云'),
        ('aws', 'AWS ECR'),
        ('azure', 'Azure ACR'),
        ('gcp', 'Google GCR'),
    ]
    registry_type = models.CharField(max_length=20, choices=REGISTRY_TYPE_CHOICES, default='private', verbose_name="仓库类型")

    # 认证信息
    AUTH_TYPE_CHOICES = [
        ('password', '用户名密码'),
        ('token', 'Robot Token'),
    ]
    auth_type = models.CharField(max_length=20, choices=AUTH_TYPE_CHOICES, default='password', verbose_name="认证方式")
    username = models.CharField(max_length=100, blank=True, verbose_name="用户名")
    password = models.CharField(max_length=255, blank=True, verbose_name="密码")  # 需要加密存储
    robot_token = models.TextField(blank=True, verbose_name="Robot Token")  # 支持长Token
    email = models.EmailField(blank=True, verbose_name="邮箱")

    # 配置选项
    is_active = models.BooleanField(default=True, verbose_name="是否启用")
    is_default = models.BooleanField(default=False, verbose_name="是否为默认仓库")
    auto_sync = models.BooleanField(default=False, verbose_name="自动同步")

    # 状态信息
    CONNECTION_STATUS_CHOICES = [
        ('unknown', '未知'),
        ('connected', '已连接'),
        ('disconnected', '连接失败'),
        ('error', '错误'),
        ('testing', '测试中'),
    ]
    connection_status = models.CharField(
        max_length=20,
        choices=CONNECTION_STATUS_CHOICES,
        default='unknown',
        verbose_name="连接状态"
    )

    # 统计信息
    repositories_count = models.IntegerField(default=0, verbose_name="仓库数量")

    # 时间戳
    last_sync_time = models.DateTimeField(null=True, blank=True, verbose_name="最后同步时间")
    last_check_time = models.DateTimeField(null=True, blank=True, verbose_name="最后检查时间")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    # 创建者
    created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="创建者")

    class Meta:
        verbose_name = "Docker镜像仓库"
        verbose_name_plural = "Docker镜像仓库"
        ordering = ['-is_default', '-created_at']

    def __str__(self):
        return f"{self.name} ({self.url})"

    def save(self, *args, **kwargs):
        # 确保只有一个默认仓库
        if self.is_default:
            DockerRegistry.objects.filter(is_default=True).exclude(pk=self.pk).update(is_default=False)
        super().save(*args, **kwargs)
